package de.rj.urwalking.data.survey;

import java.util.ArrayList;

import android.content.Context;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import de.rj.urwalking.R;
import de.rj.urwalking.config.Constants;

/**
 * 
 * A Question that shows a seven point likert scale as well as an option to rate it as not applicable.
 * 
 * @author rjj
 * 
 */

public class Likert7Question extends Question implements RadioGroup.OnCheckedChangeListener {

	private static final long serialVersionUID = 1L;
	private transient RadioGroup mainRadioGroup;
	private transient RadioGroup additionalRadioGroup;

	private transient boolean isShowingAdditionalOptions = false;

	public Likert7Question(int id, int itemNumber, String text, int scaleId, int screen) {
		super(id, itemNumber, text, scaleId, screen);

	}

	@Override
	public View buildView(Context context, ViewGroup parent) {
		LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View view = inflater.inflate(R.layout.question_likert7, parent, false);

		setQuestionText(view);
		setupLabels(view);
		setupRadioGroups(context, view);
		restoreState();

		return view;
	}

	private void setupLabels(View questionView) {
		TextView extremeLeftLabel = (TextView) questionView.findViewById(R.id.scalePointLabel1);
		TextView extremeRightLabel = (TextView) questionView.findViewById(R.id.scalePointLabel7);
		extremeLeftLabel.setText(scale.getLeftExtreme().getTitle());
		extremeRightLabel.setText(scale.getRightExtreme().getTitle());
	}

	private void setupRadioGroups(Context context, View view) {
		// both the actual scale and the n/a options are implemented as separate RadioGroups
		mainRadioGroup = (RadioGroup) view.findViewById(R.id.radioGroup);
		additionalRadioGroup = (RadioGroup) view.findViewById(R.id.naRadioGroup);

		// set regular scalepoints
		ArrayList<ScalePoint> regularScalePoints = scale.getRegularScalePoints();

		for (int i = 0; i < regularScalePoints.size(); i++) {
			RadioButton radioButton = new RadioButton(context);
			radioButton.setTag(regularScalePoints.get(i).getIntValue());
			mainRadioGroup.addView(radioButton);
		}

		// add additional scale points from database
		for (ScalePoint scalePoint : scale.getAdditionalScalePoints()) {
			RadioButton radioButton = new RadioButton(context);
			radioButton.setText(scalePoint.getTitle());
			radioButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
			radioButton.setTag(scalePoint.getIntValue());

			if (scalePoint.getIntValue() != -1) {
				radioButton.setVisibility(View.GONE);
			}

			additionalRadioGroup.addView(radioButton);
		}

		mainRadioGroup.setOnCheckedChangeListener(this);
		additionalRadioGroup.setOnCheckedChangeListener(this);
	}

	/**
	 * checks the corresponding RadioButton in either RadioGroup if there's already an answer
	 */

	private void restoreState() {

		int answerId = getAnswer().getIntAnswer();

		if (answerId == Constants.UNDEFINED) {
			mainRadioGroup.clearCheck();
			additionalRadioGroup.clearCheck();
		} else if (answerId > 0) {
			int id = mainRadioGroup.findViewWithTag(answerId).getId();
			mainRadioGroup.check(id);
		} else if (answerId < 0) {
			int id = additionalRadioGroup.findViewWithTag(answerId).getId();
			additionalRadioGroup.check(id);
		} else {
			mainRadioGroup.clearCheck();
			additionalRadioGroup.clearCheck();
		}
	}

	/**
	 * handles events for both RadioGroups
	 */

	@Override
	public void onCheckedChanged(RadioGroup group, int checkedId) {

		if (checkedId == -1) return;

		if (group.getId() == mainRadioGroup.getId()) {

			// un- and re-register the listener to avoid a never-ending loop of
			// onCheckedChanged events resulting in a stack overflow
			additionalRadioGroup.setOnCheckedChangeListener(null);
			additionalRadioGroup.clearCheck();
			additionalRadioGroup.setOnCheckedChangeListener(this);

			// save the rating according to the checked RadioButton
			View v = mainRadioGroup.findViewById(checkedId);
			int intAnswer = (Integer) v.getTag();
			updateAnswer(intAnswer);

			// hide all radiobuttons except the one showing k.a.
			int childcount = additionalRadioGroup.getChildCount();
			for (int i = 0; i < childcount; i++) {
				v = additionalRadioGroup.getChildAt(i);
				if ((Integer) v.getTag() != -1) {
					v.setVisibility(View.GONE);
				}
			}

			isShowingAdditionalOptions = false;

		} else if (group.getId() == additionalRadioGroup.getId()) {

			mainRadioGroup.setOnCheckedChangeListener(null);
			mainRadioGroup.clearCheck();
			mainRadioGroup.setOnCheckedChangeListener(this);

			if (checkedId > 0) {
				View v = additionalRadioGroup.findViewById(checkedId);
				int intAnswer = (Integer) v.getTag();
				updateAnswer(intAnswer);
			}

			if (!isShowingAdditionalOptions) {
				showAdditionalOptions();
			}

		}
	}

	private void showAdditionalOptions() {
		Animation fadeIn = new AlphaAnimation(0, 1);
		fadeIn.setDuration(500);
		int childcount = additionalRadioGroup.getChildCount();
		for (int i = 0; i < childcount; i++) {
			View v = additionalRadioGroup.getChildAt(i);
			v.setVisibility(View.VISIBLE);
			v.startAnimation(fadeIn);

		}

		isShowingAdditionalOptions = true;
	}

	@Override
	public boolean hasBeenAnswered() {

		// A Likert7Question is considered as answered if the rating has changed
		// from the initial "undefined" state.
		return getAnswer().getIntAnswer() != Constants.UNDEFINED;
	}

}
